package emulator.assembler;

public class SymbolTableEntry {
	public final static int SYMBOL_TYPE_UNKNOWN = 0;
	public final static int SYMBOL_TYPE_CODE = 1;
	public final static int SYMBOL_TYPE_DATA = 2;
	public final static int SYMBOL_TYPE_WORD = 3;
	public final static int SYMBOL_TYPE_TEXT = 4;
	public final static int SYMBOL_TYPE_CHIP = 5;
	public final static int SYMBOL_TYPE_EMPTY = 6;
	
	private int address = 0;
	private String label = null;
	private String remark = null;
	private int type = SYMBOL_TYPE_UNKNOWN;
	
	/**
	 * @return the address
	 */
	public int getAddress() {
		return address;
	}
	/**
	 * @param address the address to set
	 */
	public void setAddress(int address) {
		this.address = address;
	}
	/**
	 * @return the label
	 */
	public String getLabel() {
		return label;
	}
	/**
	 * @param label the label to set
	 */
	public void setLabel(String label) {
		this.label = label;
	}
	/**
	 * @return the remark
	 */
	public String getRemark() {
		return remark;
	}
	/**
	 * @param remark the remark to set
	 */
	public void setRemark(String remark) {
		this.remark = remark;
	}
	/**
	 * @return the type
	 */
	public int getType() {
		return type;
	}
	/**
	 * @param type the type to set
	 */
	public void setType(int type) {
		this.type = type;
	}
	
	public static SymbolTableEntry createFromString(String string) {
		SymbolTableEntry entry = null;
		if (string != null)
		{
			String line = string.trim();
			if (!line.isEmpty() && line.charAt(0) != ';')
			{
				String[] words = line.split("[\\s\t]+");
				if (words.length > 0)
				{
					if (words[0].equals("al"))
						entry = parseLabelLine(words);
					else
						entry = parseSymbolLine(words);
				}
			}
		}
		return entry;
	}
	
	private static SymbolTableEntry parseLabelLine(String[] words) {
		SymbolTableEntry entry = null;
		if (words.length >= 3)
		{
			int address = Integer.parseInt(words[1], 16);
			String label = words[2];
			if (!label.endsWith("__"))
			{
				if (label.charAt(0) == '.')
					label = label.substring(1);
				entry = new SymbolTableEntry();
				entry.setAddress(address);
				entry.setLabel(label);
			}
		}
		return entry;
	}
	
	private static SymbolTableEntry parseSymbolLine(String[] words) {
		SymbolTableEntry entry = null;
		if (words.length >= 2)
		{
			int address = Integer.parseInt(words[0], 16);
			if (address >= 0 && address <= 0xFFFF)
			{
				entry = new SymbolTableEntry();
				entry.setAddress(address);
				if (words[1].length() > 1)
					entry.setLabel(words[1]);
				int last_word = words.length-1;
				if (last_word > 1)
				{
					int type = getTypeFromString(words[last_word]);
					if (type != SYMBOL_TYPE_UNKNOWN)
					{
						entry.setType(type);
						last_word--;
					}
					else
						entry.setType(SYMBOL_TYPE_CODE);
					if (last_word > 1)
					{
						String remark = words[2];
						for (int i = 3; i <= last_word; i++)
							remark += " "+words[i];
						if (!remark.isEmpty())
							entry.setRemark(remark);
					}
				}
				else
					entry.setType(SYMBOL_TYPE_CODE);
			}
		}
		return entry;
	}
	private static int getTypeFromString(String type_string) {
		int type = SYMBOL_TYPE_UNKNOWN;
		if (type_string.equals("CODE"))
			type = SYMBOL_TYPE_CODE;
		else if (type_string.equals("DATA"))
			type = SYMBOL_TYPE_DATA;
		else if (type_string.equals("WORD"))
			type = SYMBOL_TYPE_WORD;
		else if (type_string.equals("TEXT"))
			type = SYMBOL_TYPE_TEXT;
		else if (type_string.equals("CHIP"))
			type = SYMBOL_TYPE_CHIP;
		else if (type_string.equals("EMPTY"))
			type = SYMBOL_TYPE_EMPTY;
		return type;
	}
	
}
